<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2017/11/29
 * Time: 9:22
 */

namespace common\business\qywx;

use common\business\CommonHelper;
use common\business\QywxHelper;
use common\consts\CommonResources;
use common\helpers\StringUtil;
use common\models\Department;
use common\models\Log;
use common\models\qywx\QywxDepartment;
use Yii;
use common\result\ActionResult;
use yii\helpers\Json;

class QywxDepartmentApiHandler extends QywxApiHandler
{
    /**
     * @param $jsonArr
     * @param callback|null $writeBackHandler
     * @return bool
     */
    public function createByJsonStr($jsonStr, $writeBackHandler = null){
        $url = $this->baseUrl . '/department/create';
        $params = [
            'access_token' => QywxHelper::getAccessTokenVal(),
        ];
        return $this->postJson($url, $params, $jsonStr, $writeBackHandler);
    }

    /**
     * @param $jsonArr
     * @param callback|null $writeBackHandler
     * @return bool
     */
    public function updateByJsonStr($jsonStr, $writeBackHandler = null){
        $url = $this->baseUrl . '/department/update';
        $params = [
            'access_token' => QywxHelper::getAccessTokenVal(),
        ];
        return $this->postJson($url, $params, $jsonStr, $writeBackHandler);
    }

    /**
     * 得到企业微信组织列表
     * @param string|null $parentQywxId
     * @param callback|null $writeBackHandler
     * @return bool
     */
    public function getJsonList($parentQywxId = null, $writeBackHandler = null){
        if (StringUtil::isNullOrWhiteSpace($parentQywxId)){
            $parentQywxId = 0;
        }
        $url = $this->baseUrl . '/department/list';
        $params = [
            'access_token' => QywxHelper::getAccessTokenVal(),
            'id' => $parentQywxId,
        ];
        return $this->getJson($url, $params, $writeBackHandler);
    }

    /**
     * 删除企业微信上组织
     * @param $qywx_id string
     * @param callback|null $successHandler
     * @return bool
     */
    public function delete($qywx_id, $successHandler = null){
        if (StringUtil::isNullOrWhiteSpace($qywx_id)){
            $this->addError('delete on Qywx', 'qywx_id is null');
            return false;
        }

        $url = $this->baseUrl . '/department/delete';
        $params = [
            'access_token' => QywxHelper::getAccessTokenVal(),
            'id' => $qywx_id,
        ];
        return $this->getJson($url, $params, $successHandler);
    }

    /**查找一个department列表里对应的部门，先按照id找，没有的话再按照name找
     * @param $departmentList array
     * @param $name string
     * @param $parentId string
     * @param $wx_id string
     * @return array
     */
    protected function findInList($departmentList, $name, $parentId, $wx_id = null){
        if (!StringUtil::isNullOrWhiteSpace($wx_id)){
            foreach ($departmentList as $item){
                if (strtolower($wx_id) == strtolower($item['id']) && (strtolower($parentId) == strtolower($item['parentid']))){
                    return $item;
                }
            }
        }
        foreach ($departmentList as $item){
            if (strtolower($name) == strtolower($item['name']) && (strtolower($parentId) == strtolower($item['parentid'])))
                return $item;
        }
        return null;
    }

    /**
     * @param QywxDepartment $obj
     * @param bool $isCreate
     * @return ActionResult
     */
    public function createOrUpdateQywxDepartment($obj, $isCreate = true){
        $wxPlatformResult = new ActionResult();
        $getWriteBackHandler = function($errcode, $errmsg, $department = null) use ($obj, $wxPlatformResult) {
            if (intval($errcode) == 0){
                $newObj = $this->findInList($department, $obj->name, $obj->parent_wx_id, $obj->wx_id);
                if (!$newObj){
                    $infoJson = Json::encode([
                        'name' => $obj->name,
                        'parentid' => $obj->parent_wx_id,
                    ]);

                    $writeBackHandler = function ($errcode, $errmsg, $dbId = null) use ($obj, $wxPlatformResult){
                        if (intval($errcode) > 0){
                            $errMsg = sprintf('{ errcode: %s, errormsg: %s }', $errcode, $errmsg);
                            $this->addError('Create On Qywx', $errMsg);
                            $wxPlatformResult->addSubResult(new ActionResult(false, $errMsg));
                        }
                        else {
                            if (!StringUtil::isNullOrWhiteSpace($dbId)){
                                $obj->wx_id = $dbId;
                            }
                        }
                    };
                    $this->createByJsonStr($infoJson, $writeBackHandler);
                }
                else {
//                    已存在无需更新
                    $obj->wx_id = $newObj['id'];
                    $wxPlatformResult->setMessage('Department already exists in Qywx Platform, do not need change');
                }
            }
            else {
                $objInDb = QywxDepartment::findOne([
                    'name' => $obj->name,
                    'number' => $obj->number,
                ]);
                if ($objInDb){
                    $this->delete($objInDb);
                }

                $errMsg = sprintf('{ errcode: %s, errormsg: %s }', $errcode, $errmsg);
                $this->addError('Create On Qywx', $errMsg);
                $wxPlatformResult->addSubResult(new ActionResult(false, $errMsg));
            }
        };

        $this->getJsonList($obj->parent_wx_id, $getWriteBackHandler);
        if (!$wxPlatformResult->isSuccess){
            return new ActionResult(false, $this->getErrorsMessage());
        }

        return $isCreate ?  $this->create($obj) : $this->updateQywxDepartmentInDb(QywxDepartment::findOne($obj->id));
    }

    /**
     * @param QywxDepartment $department
     * @return ActionResult
     */
    public function updateQywxDepartmentInDb($qywxDepartment){
        $oldObj = QywxDepartment::findOne([
            'id' => $qywxDepartment->id,
        ]);
        return $this->update($qywxDepartment, $oldObj, [
            'name',
            'wx_id',
            'parent_wx_id',
            'order',
            'memo',
        ]);
    }
}